//
//  KSUITextField.swift
//  KaisafinStockSwift
//
//  Created by 云 on 2020/1/2.
//  Copyright © 2020 administrator. All rights reserved.
//

import UIKit

// MARK: - TextFieldCounterDelegate

protocol TextFieldCounterDelegate: class {
    func didReachMaxLength(textField: BYUITextField)
}

 class BYUITextField: TextField, UITextFieldDelegate {

    open var lineView: UIView!
    weak var counterDelegate: TextFieldCounterDelegate?
    
    open var placeholderColor: UIColor = UIColor.lightGray {
        didSet {
            updatePlaceholder()
        }
    }
    
    open var placeholderFont: UIFont? {
        didSet {
            updatePlaceholder()
        }
    }
  
    open var showLine : Bool = false {
        didSet {
            updateLineView()
        }
    }
    
    open var lineHeight: CGFloat = 0.5 {
        didSet {
            updateLineView()
            setNeedsDisplay()
        }
    }
    
    open var lineColor: UIColor = .lightGray {
        didSet {
            updateLineView()
        }
    }
    
    open var maxLength: Int = NSIntegerMax{
        didSet {
            if maxLength <= 0 {
                maxLength = NSIntegerMax
            }
        }
    }
    
    open var leftSpace: CGFloat = 0.0 {
        didSet {
            let leftView = UIView(frame: CGRect(x: 0, y: 0, width: self.leftSpace, height: self.frame.size.height))
            self.leftView = leftView
            self.leftViewMode = .always
        }
    }
    
    
    private weak var _delegate: UITextFieldDelegate?
    open override var delegate: UITextFieldDelegate? {
        set {
            self._delegate = newValue
        }
        get {
            return self._delegate
        }
    }
    
    
    override public init(frame: CGRect) {
        super.init(frame: frame)
        super.delegate = self
        createLineView()
    }

    /**
     Intialzies the control by deserializing it
     - parameter aDecoder the object to deserialize the control from
     */
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
    }
    
    deinit {
        
    }
    
    // MARK:- UITextFieldDelegate
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        
        var shouldChange = false
        let charactersCount = textFieldCharactersCount(textField: textField, string: string, changeCharactersIn: range)
        
        if string.isEmpty {
            shouldChange = true
        } else {
            shouldChange = charactersCount <= maxLength
        }
        
        callDidReachMaxLengthDelegateIfNeeded(count: charactersCount)
        //避免明文切换成密文后被清空
//        var toBeStr = textField.text
//        toBeStr = toBeStr?.replacingCharacters(in: range.toRange(string: toBeStr ?? ""), with: string)
//
//        if textField.isSecureTextEntry {
//            textField.text = toBeStr
//            return false
//        }
        
        return shouldChange && (delegate?.textField?(textField, shouldChangeCharactersIn: range, replacementString: string) ?? true)
    }
    
    
    // MARK: - UITextFieldDelegate Forwarding

    public func textFieldDidBeginEditing(_ textField: UITextField) {
        delegate?.textFieldDidBeginEditing?(self)
    }
    
    public func textFieldDidEndEditing(_ textField: UITextField) {
        delegate?.textFieldDidEndEditing?(self)
    }
    
    public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        return delegate?.textFieldShouldReturn?(self) ?? true
    }
    
    public func textFieldShouldClear(_ textField: UITextField) -> Bool {
        return delegate?.textFieldShouldClear?(self) ?? true
    }
    
    public override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        return false
    }
    
    
    private func textFieldCharactersCount(textField: UITextField, string: String, changeCharactersIn range: NSRange) -> Int {
        
        var textFieldCharactersCount = 0
        
        if let textFieldText = textField.text {
            
            if !string.isEmpty {
                textFieldCharactersCount = textFieldText.count + string.count - range.length
            } else {
                textFieldCharactersCount = textFieldText.count - range.length
            }
        }
        
        return textFieldCharactersCount
    }
    
    
    private func callDidReachMaxLengthDelegateIfNeeded(count: Int) {
        guard count >= maxLength else { return }
        counterDelegate?.didReachMaxLength(textField: self)
    }

}


extension BYUITextField{
    
    fileprivate func updatePlaceholder() {
        guard let placeholder = placeholder, let font = placeholderFont ?? font else {
            return
        }
        attributedPlaceholder = NSAttributedString(
            string: placeholder,
            attributes: [
                NSAttributedString.Key.foregroundColor: placeholderColor, NSAttributedString.Key.font: font
            ]
        )
    }
    
    fileprivate func createLineView() {

        if lineView == nil {
            lineView = UIView()
            lineView.isUserInteractionEnabled = false
            configureDefaultLineHeight()
            lineView.autoresizingMask = [.flexibleWidth, .flexibleTopMargin]
            
            addSubview(lineView)
        }

    }
    
    
    fileprivate func updateLineView() {
        guard let lineView = lineView else {
            return
        }
        
        if showLine {
            lineView.isHidden = false
            return
        }else{
            lineView.isHidden = true
        }

        lineView.frame = lineViewRectForBounds(bounds)
        updateLineColor()
    }
    
    fileprivate func updateLineColor() {
        guard let lineView = lineView else {
            return
        }
        
        lineView.backgroundColor = lineColor
    }

    
    fileprivate func configureDefaultLineHeight() {
        let onePixel: CGFloat = 1.0 / UIScreen.main.scale
        lineHeight = 2.0 * onePixel
    }
    
    open func lineViewRectForBounds(_ bounds: CGRect) -> CGRect {
        let height = lineHeight
        return CGRect(x: 0, y: bounds.size.height - height, width: bounds.size.width, height: height)
    }

}
